package com.googlecode.sere.http

import com.googlecode.sere.util.Logging
import com.googlecode.sere.method._
import com.googlecode.sere.core.{TrivialAuthenticator, InvocationData}

object RestEngine extends Logging {
	
	def process(req: HttpRequest, res: HttpResponse) = try {
		val httpWritable = dispatchMethod(req)
    httpWritable.writeToHttpResponse(res)
	} catch {
    case ex => handleInternalError(ex)
  }

  private def dispatchMethod(req: HttpRequest): HttpWritable = try {
    val httpMethod = selectMethod(req)
    val invocationData = callInterceptorChain(req)
    httpMethod.process(invocationData)
	} catch {
    case httpEx: HttpException => httpEx
  }

  private def callInterceptorChain(req: HttpRequest) = {
    // TODO: Do well
    new TrivialAuthenticator("xxx").intercept(req)
  }
  
  private def selectMethod(req: HttpRequest) = req.method match {
    case "get" => {
      // TODO: Map ConditionalGet if header If-None-Match
      GetMethod.fromRequest(req)
    }
    case "put" => PutMethod.fromRequest(req)
    case "delete" => DeleteMethod.fromRequest(req)
    case "post" => PostMethod.fromRequest(req)
    case other => throw new NotImplemented("Unknown method %s" format other)
  }

  private def handleInternalError(ex: Throwable) {
    logger.error("Internal error", ex)
    throw ex
	}
}
